import psutil
import smtplib
from email.mime.text import MIMEText
import time
import logging

# 配置日志输出
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('server_monitor.log'),
        logging.StreamHandler()
    ]
)

# 1. 邮箱配置（请替换为实际信息）
SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 465  # QQ邮箱SSL端口
FROM_EMAIL = "804177352@qq.com"
TO_EMAIL = "15829065732@163.com"
EMAIL_PWD = "zelguepzhcixbcfb"  # 邮箱授权码，非登录密码

# 2. 告警阈值配置（根据实际需求调整）
CPU_THRESHOLD = 10  # CPU使用率阈值(%)
MEM_THRESHOLD = 10  # 内存使用率阈值(%)
DISK_THRESHOLD = 85  # 磁盘使用率阈值(%)
CHECK_INTERVAL = 300  # 检查间隔(秒)

# 3. 发送告警邮件
def send_alert(content):
    try:
        msg = MIMEText(content, "plain", "utf-8")
        msg["From"] = FROM_EMAIL
        msg["To"] = TO_EMAIL
        msg["Subject"] = "【服务器告警】硬件资源使用率超标"
        
        # 使用SSL加密连接
        with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
            server.login(FROM_EMAIL, EMAIL_PWD)
            server.sendmail(FROM_EMAIL, TO_EMAIL, msg.as_string())
        
        logging.info("告警邮件发送成功")
        return True
    except smtplib.SMTPException as e:
        logging.error(f"邮件发送失败: {str(e)}")
        return False
    except Exception as e:
        logging.error(f"发送邮件时发生错误: {str(e)}")
        return False

# 4. 监控硬件状态
def monitor_server():
    try:
        # 获取硬件使用率
        cpu_usage = psutil.cpu_percent(interval=1)
        mem = psutil.virtual_memory()
        mem_usage = mem.percent
        disk_usage = psutil.disk_usage("/").percent
        
        # 日志输出当前状态
        logging.info(f"CPU使用率: {cpu_usage}% | 内存使用率: {mem_usage}% | 磁盘使用率: {disk_usage}%")
        
        # 检查是否超过阈值
        alert_msg = ""
        if cpu_usage > CPU_THRESHOLD:
            alert_msg += f"CPU使用率超标: {cpu_usage}% (阈值: {CPU_THRESHOLD}%)\n"
        if mem_usage > MEM_THRESHOLD:
            alert_msg += f"内存使用率超标: {mem_usage}% (阈值: {MEM_THRESHOLD}%)\n"
        if disk_usage > DISK_THRESHOLD:
            alert_msg += f"磁盘使用率超标: {disk_usage}% (阈值: {DISK_THRESHOLD}%)\n"
        
        # 发送告警
        if alert_msg:
            # 添加服务器信息（如果是远程监控，可替换为实际服务器IP）
            alert_msg = f"服务器监控告警:\n{alert_msg}"
            send_alert(alert_msg)
            logging.warning(f"触发告警: \n{alert_msg}")
            
    except Exception as e:
        logging.error(f"监控过程中发生错误: {str(e)}")

# 5. 主循环
def main():
    logging.info("服务器监控程序启动...")
    logging.info(f"监控阈值 - CPU: {CPU_THRESHOLD}% | 内存: {MEM_THRESHOLD}% | 磁盘: {DISK_THRESHOLD}%")
    logging.info(f"检查间隔: {CHECK_INTERVAL}秒")
    
    try:
        while True:
            monitor_server()
            time.sleep(CHECK_INTERVAL)
    except KeyboardInterrupt:
        logging.info("用户终止程序，监控结束")
    except Exception as e:
        logging.error(f"程序发生致命错误: {str(e)}", exc_info=True)

if __name__ == "__main__":
    main()
